package com.zts.base;

/**
 * Created by Zhangkh on 2017/5/31.
 */

import com.zts.base.page.PagedList;
import com.zts.base.resource.BaseResource;
import com.zts.base.resource.ListResource;
import com.zts.base.resource.PagedResource;
import org.springframework.beans.BeanUtils;
import org.springframework.hateoas.Identifiable;
import org.springframework.hateoas.mvc.ResourceAssemblerSupport;

import java.util.ArrayList;
import java.util.List;

/**
 * 基础资源装配类，继承自ResourceAssemblerSupport，提供将实体对象类T 转换为资源对象D 的方法。
 * ResourceAssemblerSupport 来源于 Spring HATEOAS，遵循HATEOAS规范，转换后的资源中自动包含了动态的链接信息。
 * Created by kunchen on 16/5/30.
 */
public class BasicResourceAssembler<T extends Identifiable, D extends BaseResource>
        extends ResourceAssemblerSupport<T,D> {

    public BasicResourceAssembler(Class<?> controller, Class<D> resource) {super(controller,resource);}

    @Override
    public D toResource(T entity) {
        if (entity == null){
            return (D)new BaseResource();
        }

        D resource = createResourceWithId(entity.getId(),entity);
        BeanUtils.copyProperties(entity,resource);

        return resource;
    }

    @Override
    public List<D> toResources(Iterable<? extends T> entities)  {
        return entities == null ? new ArrayList<D>() : super.toResources(entities);

    }

    public ListResource<D> toListResource(Iterable<? extends T> entities, Long total) {
        ListResource<D> resource = new ListResource<>();

        List<D> items = toResources(entities);
        resource.setTotal(total == null? items.size() : total);
        resource.setCount(items.size());
        resource.setItems(items);

        return resource;

    }

    public PagedResource<D> toPagedResource(PagedList<? extends T> pageList) {
        PagedResource<D> resource = new PagedResource<>();

        List<D> items = toResources(pageList);

        resource.setTotal(pageList.getTotal());
        resource.setCount(pageList.getCount());
        resource.setOffset(pageList.getOffset());
        resource.setLimit(pageList.getLimit());
        resource.setSize(pageList.getLimit());
        resource.setPage(pageList.getOffset() / pageList.getLimit() + 1);
        resource.setItems(items);

        return resource;
    }

    @SuppressWarnings("unchecked")
    public ListResource<D> toListResource(Iterable<? extends T> entities) {
        return entities instanceof PagedList
                ? toPagedResource((PagedList<T>) entities)
                : this.toListResource(entities, null);
    }
}